import requests

GET_CITY_INFO_API_URL = 'https://geoapi.qweather.com/v2/city/lookup?'
GET_WEATHER_INFO_API_URL = 'https://devapi.qweather.com/v7/weather/3d?'

class RequestAPI_failed(Exception):
    pass


class ValueNotCached(Exception):
    pass


class MyWeather():
    headers = {
        'Accept' : 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
        'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
    }

    def __init__(self, city : str, api_key : str) -> None:
        self.city = city
        self.api_key = api_key
        self.cache = {}


    def getRequestAPI(self, url : str) -> dict:
        res = requests.get(url + '&key={}'.format(self.api_key), headers = self.headers).json()
        if res['code'] != '200':
            raise RequestAPI_failed('api code = {}'.format(res['code']))

        return res


    def getCachedValue(self, key : str) -> str | dict:
        if key not in self.cache.keys():
            raise ValueNotCached('key = {}'.format(key))

        return self.cache[key]


    def cacheValue(self, key : str, value : str | dict):
        self.cache[key] = value


    def GetCityId(self) -> str:
        CITY_ID_KEY = 'city_id'
        try:
            city_id = self.getCachedValue(CITY_ID_KEY)
        except ValueNotCached:
            res = self.getRequestAPI(
                GET_CITY_INFO_API_URL + "location={}".format(self.city)
            )
            city_id = res['location'][0]['id']
            self.cacheValue(CITY_ID_KEY, city_id)

        return city_id


    def GetWeatherInfo(self) -> dict:
        WEATHER_INFO_KEY = 'weather_info'
        try:
            weather_info = self.getCachedValue(WEATHER_INFO_KEY)
        except ValueNotCached:
            city_id = self.GetCityId()
            res = self.getRequestAPI(
                GET_WEATHER_INFO_API_URL + "location={}".format(city_id)
            )
            weather_info = res['daily'][0]
            self.cacheValue(WEATHER_INFO_KEY, weather_info)

        return weather_info


    def FlushCache(self):
        self.cache.clear()